﻿#pragma once

// 防止 Windows API 宏污染
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include "aimbot.h"
#include <algorithm> // 添加这行
#include <cmath>
#include <string>
#include "../cs2 dumper/client_dll.hpp"
#include "../cs2 dumper/offsets.hpp"
#include "../PlayerData/PlayerData.h"
#include "../messagebox/messagebox.h"
#include "../movement/movement.h"
#include "../ESP/vision.h"
#include "../../dll_main.h"
#include "../GameTrace/GameTrace.h"
#include "../function/KEY/KEY.h"
#include "../../cs2 dumper/server_dll.hpp"
using namespace all_settings;

// 定义需要检查的武器ID数组
constexpr int SHORT_RANGE_WEAPONS[] = { 8, 9,11, 40 };

Vector3 CalculateAimAngle(const Vector3& localPos,
    const Vector3& targetPos,
    const Vector3& currentAngles,
    float smoothFactor)
{
    Vector3 dir = targetPos - localPos;
    dir.Normalize();

    // 计算原始目标角度（无平滑）
    float targetYaw = atan2f(dir.y, dir.x) * (180.0f / M_PI);
    float targetPitch = atan2f(-dir.z, sqrtf(dir.x * dir.x + dir.y * dir.y)) * (180.0f / M_PI);

    Vector3 newAngles;

    // 当smoothFactor为0时完全无平滑（直接锁定）
    if (smoothFactor == 0.0f) {
        newAngles.x = targetPitch;
        newAngles.y = targetYaw;
    }
    else {
        float targetYaw = atan2f(dir.y, dir.x) * (180.0f / M_PI);
        float targetPitch = atan2f(-dir.z, sqrtf(dir.x * dir.x + dir.y * dir.y)) * (180.0f / M_PI);
        float smoothFactor2 = std::clamp(0.4f - (smoothFactor * 0.015f), 0.05f, 0.35f);

        newAngles.x = currentAngles.x + std::remainder(targetPitch - currentAngles.x, 360.0f) * smoothFactor2;
        newAngles.y = currentAngles.y + std::remainder(targetYaw - currentAngles.y, 360.0f) * smoothFactor2;
    }

    newAngles.z = 0.0f;
    return newAngles;
}

std::vector<TargetInfo> g_targetList;
uintptr_t g_lastTargetPawn = 0;

bool set_view_angle(Vector3 Angle) {
    static auto client = reinterpret_cast<uintptr_t>(GetModuleHandle(L"client.dll"));

    if (!client) {
        return false;
    }

    auto viewAngles = reinterpret_cast<Vector3*>(client + cs2_dumper::offsets::client_dll::dwViewAngles);
    if (!viewAngles) {
        return false;
    }

    // 保存原始角度用于比较
    Vector3 originalAngle = *viewAngles;

    // 规范化角度
    Angle.x = std::clamp(Angle.x, -89.0f, 89.0f);
    Angle.y = std::remainder(Angle.y, 360.0f);
    Angle.z = 0.0f;

    // 设置新角度
    *viewAngles = Angle;

    // 检查是否成功设置
    Vector3 newAngle = *viewAngles;

    // 使用浮点数比较的容差值
    const float tolerance = 0.001f;

    bool success = (std::abs(newAngle.x - Angle.x) < tolerance) &&
        (std::abs(newAngle.y - Angle.y) < tolerance) &&
        (std::abs(newAngle.z - Angle.z) < tolerance);
    return success;
}

// 武器精度数据结构
struct WeaponAccuracyData {
    float minSpread;        // 最小散布（最佳精度）
    float maxSpread;        // 基础最大散布
    float crouchMultiplier; // 蹲下精度乘数
    float moveMultiplier;   // 移动精度乘数
    float jumpMultiplier;   // 跳跃精度乘数
    float maxSpreadLimit;   // 最大散布限制
    float penaltyMultiplier; // 精度惩罚乘数（增强效果）
};

WeaponAccuracyData GetWeaponAccuracyData(int weaponid) {
    WeaponAccuracyData data = { 0.1f, 0.8f, 0.6f, 2.5f, 4.0f, 1.5f, 1.8f };

    // 根据武器ID设置不同的精度参数（缩小了最大精度值）
    switch (weaponid) {
        // 狙击枪 - 高精度武器
    case 9:  // AWP
    case 11: // G3SG1
    case 38: // SCAR20
    case 40: // SSG08
        data = { 0.05f, 1.5f, 0.5f, 2.0f, 3.5f, 0.8f, 50.0f };
        break;

        // 步枪 - 中等精度
    case 7:  // AK-47
    case 8:  // AUG
    case 10: // FAMAS
    case 13: // 加利尔AR
    case 16: // M4A4
    case 39: // SG553
    case 60: // M4A1消音型
        data = { 0.08f, 2.0f, 0.6f, 2.2f, 3.8f, 1.2f, 100.0f };
        break;

        // 手枪 - 低精度，大变化
    case 1:  // 沙漠之鹰
    case 2:  // 双枪贝瑞塔
    case 3:  // FN57
    case 4:  // 格洛克
    case 32: // P2000
    case 36: // P250
    case 30: // Tec9冲锋枪
    case 61: // USP消音型
    case 63: // CZ75自动手枪
    case 64: // R8左轮
        data = { 0.12f, 2.0f, 0.7f, 3.0f, 4.5f, 1.8f, 80.0f };
        break;

        // 霰弹枪 - 大散布
    case 25: // XM1014霰弹枪
    case 27: // MAG7霰弹枪
    case 29: // 截短霰弹枪
    case 35: // 新星霰弹枪
        data = { 0.15f, 2.5f, 0.8f, 3.5f, 5.0f, 2.5f, 50.0f };
        break;

        // 冲锋枪 - 中等散布
    case 17: // MAC-10
    case 19: // P90
    case 23: // MP5消音版
    case 24: // UMP45
    case 26: // 野牛冲锋枪
    case 33: // MP7
    case 34: // MP9
        data = { 0.1f, 2.9f, 0.65f, 2.8f, 4.2f, 1.6f, 80.0f };
        break;

        // 机枪 - 大散布，但相对稳定
    case 14: // M249
    case 28: // 内格夫
        data = { 0.18f,2.2f, 0.75f, 3.2f, 4.8f, 2.0f, 40.5f };
        break;

        // 特殊武器
    case 31: // 宙斯电击枪
        data = { 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 4.0f };
        break;

        // 默认值（其他武器）
    default:
        data = { 0.1f, 0.8f, 0.6f, 2.5f, 4.0f, 1.5f, 1.8f };
        break;
    }

    return data;
}

// 获取当前武器的精度信息
bool GetWeaponAccuracyInfo(PlayerData localPawn, uintptr_t client, float& flCurrentAccuracy, float& flMinAccuracy, float& flMaxAccuracy , float& accuracyPercentage) {
    if (!localPawn.pawn || !client) return false;

    // 获取武器服务
    uintptr_t weaponServices = *reinterpret_cast<uintptr_t*>(
        localPawn.pawn + cs2_dumper::schemas::client_dll::C_BasePlayerPawn::m_pWeaponServices);

    if (!weaponServices) return false;

    // 获取当前武器
    uintptr_t active_weapon_handle = *reinterpret_cast<uintptr_t*>(
        weaponServices + cs2_dumper::schemas::client_dll::CPlayer_WeaponServices::m_hActiveWeapon);

    auto activeWeapon = GetBaseEntityFromHandle(active_weapon_handle, client);
    if (!activeWeapon) return false;

    // 获取基础精度惩罚值
    float flBasePenalty = *reinterpret_cast<float*>(activeWeapon + cs2_dumper::schemas::client_dll::C_CSWeaponBase::m_fAccuracyPenalty);

    // 获取玩家状态
    bool isCrouching = *reinterpret_cast<bool*>(localPawn.pawn + cs2_dumper::schemas::client_dll::C_BaseEntity::m_fFlags) & 0x2;
    Vector3 velocity = *reinterpret_cast<Vector3*>(localPawn.pawn + cs2_dumper::schemas::client_dll::C_BaseEntity::m_vecVelocity);
    bool isMoving = localPawn.speed > 10.0f;
    bool isInAir = !(*reinterpret_cast<bool*>(localPawn.pawn + cs2_dumper::schemas::client_dll::C_BaseEntity::m_fFlags) & 0x1);

    // 获取武器类型数据
    WeaponAccuracyData accuracyData = GetWeaponAccuracyData(localPawn.weaponID);

    flMinAccuracy = accuracyData.minSpread / accuracyData.crouchMultiplier;

    flMaxAccuracy = accuracyData.maxSpread;

    flCurrentAccuracy = accuracyData.minSpread;

    // 应用状态修正到当前精度 - 增强效果
    if (isCrouching) {
        flCurrentAccuracy *= accuracyData.crouchMultiplier;  // 蹲下减少散布
    }
    if (isMoving) {
        // 移动时根据速度增加散布效果
        float speedFactor = std::min(localPawn.speed / 300.0f, 2.0f);
        flCurrentAccuracy *= (accuracyData.moveMultiplier * (0.8f + speedFactor * 0.4f));
    }
    if (isInAir) {
        // 空中大幅增加散布
        flCurrentAccuracy *= (accuracyData.jumpMultiplier * 1.2f);
    }
    if (flBasePenalty > 0) {
        // 增强精度惩罚效果
        float enhancedPenalty = flBasePenalty * accuracyData.penaltyMultiplier;
        flCurrentAccuracy *= (1.0f + enhancedPenalty);
    }

    // 确保当前精度在合理范围内
    flCurrentAccuracy = std::max(flCurrentAccuracy, accuracyData.minSpread);  // 不低于最小精度
    flCurrentAccuracy = std::min(flCurrentAccuracy, accuracyData.maxSpreadLimit); // 不高于最大限制
    accuracyPercentage = 100.0f * (1.0f - (flCurrentAccuracy - flMinAccuracy) / (flMaxAccuracy - flMinAccuracy));
    accuracyPercentage = std::clamp(accuracyPercentage, 0.0f, 100.0f);


    return true;
}

void aimbot() {
    if (!all_settings::aimbot_anitaimbot::aimbot::open_aimbot.enabled) {
        return;
    }

    static auto client = reinterpret_cast<uintptr_t>(GetModuleHandle(L"client.dll"));
    if (!client) return;

    auto Matrix = reinterpret_cast<float*>(client + cs2_dumper::offsets::client_dll::dwViewMatrix);
    if (!Matrix) return;


    const ImVec2 displaySize = ImGui::GetIO().DisplaySize;
    const float w = displaySize.x;
    const float h = displaySize.y;
    ImVec2 screenCenter(w / 2.0f, h / 2.0f);

    auto& playerDataManager = PlayerDataManager::GetInstance();
    auto localPlayer = playerDataManager.GetLocalPlayerData();

    // 检查本地玩家是否有效
    if (!localPlayer.pawn || localPlayer.health <= 0) {
        g_lastTargetPawn = 0;
        return;
    }

    auto autostop = all_settings::aimbot_anitaimbot::aimbot::autostop;
    auto autofire = all_settings::aimbot_anitaimbot::aimbot::autofire;
    auto autoScoped = all_settings::aimbot_anitaimbot::aimbot::autoScoped;

    if (WEAPON_NAMES.count(localPlayer.weaponID) == 0) {
        g_lastTargetPawn = 0;
        is_short = false;
        return;
    }

    auto& weaponSettings = all_settings::aimbot_anitaimbot::aimbot::aimbot_weapon_settings;

    // 检查武器设置是否存在
    if (weaponSettings.find(localPlayer.weaponID) == weaponSettings.end() ||
        weaponSettings.find(0) == weaponSettings.end()) {
        g_lastTargetPawn = 0;
        is_short = false;
        return;
    }

    auto& current_settings = weaponSettings[localPlayer.weaponID];
    auto& default_settings = weaponSettings[0];

    all_settings::aimbot_anitaimbot::aimbot::WeaponSettings temp_settings;
    if (current_settings.enabled) {
        temp_settings = current_settings;
    }
    else if (default_settings.enabled) { 
        temp_settings = default_settings;
    }
    else {
        return;
    }

    auto autowall = temp_settings.autowall;

    float radius = temp_settings.fov * 4;
    if (localPlayer.isScoped)
    {
        radius = radius * 2;
    }

    Vector3 currentViewAngles = *reinterpret_cast<Vector3*>(client + cs2_dumper::offsets::client_dll::dwViewAngles);
    auto eyePosOpt = GetEyePos(localPlayer.pawn);
    if (!eyePosOpt.has_value()) return;
    Vector3 local_eye_pos = eyePosOpt.value();


    g_targetList.clear();
    auto Players = playerDataManager.GetPlayersData();
    if (Players.empty()) {
        g_lastTargetPawn = 0;
        return;
    }

    for (const auto& player : Players) {
        // 跳过无效玩家
        if (!player.pawn || player.health <= 0) continue;

        if (all_settings::aimbot_anitaimbot::aimbot::team_pd)
        {
            if (player.team == localPlayer.team)
            {
                continue;
            }
        }

        int selectedBoneID = GetSelectedBoneID(temp_settings.bone_settings);

        auto headPosOpt = BonePos(player.pawn, selectedBoneID);
        if (!headPosOpt.has_value()) continue;

        Vector3 targetDir = headPosOpt.value() - local_eye_pos;

        Vector3 headPos2d{};
        if (WorldToScreen(headPosOpt.value(), headPos2d, Matrix, w, h))
        {

            float screenDistance = sqrtf(
                powf(headPos2d.x - screenCenter.x, 2) +
                powf(headPos2d.y - screenCenter.y, 2)
            );

            if (screenDistance <= radius)
            {
                if (!all_settings::aimbot_anitaimbot::aimbot::gqs)
                {
                    CGameTrace pGameTrace = Ray::TraceShape(local_eye_pos, headPosOpt.value(), localPlayer.pawn, 0xC3003);
                    if (pGameTrace.pHitEntity == (void*)player.pawn)
                    {
                        float targetDistance = targetDir.Length();
                        g_targetList.emplace_back(TargetInfo{
                            player.name,
                            screenDistance,
                            headPosOpt.value(),
                            player.pawn,
                            });
                        continue;
                    }
                    if (autowall)
                    {
                        float autowall_fw = temp_settings.autowall_fw;
                        const Vector3 offsets[] = {
                            {autowall_fw,0,0},          // 右
                            {-autowall_fw,0,0},          // 左
                            {0,autowall_fw,0},          // 上
                            {0,-autowall_fw,0},          // 下
                            {0,0,autowall_fw}, // 前
                            {0,0,-autowall_fw}  // 后
                        };
                        for (const auto& offset : offsets)
                        {
                            Vector3 eye_pos = local_eye_pos;
                            eye_pos.x += offset.x;
                            eye_pos.y += offset.y;
                            eye_pos.z += offset.z;
                            CGameTrace pGameTrace = Ray::TraceShape(eye_pos, headPosOpt.value(), localPlayer.pawn, 0xC3003);
                            if (pGameTrace.pHitEntity == (void*)player.pawn)
                            {
                                float targetDistance = targetDir.Length();
                                g_targetList.emplace_back(TargetInfo{
                                    player.name,
                                    screenDistance,
                                    headPosOpt.value(),
                                    player.pawn,
                                    });
                                break; // 只要有一个方向命中就停止检测
                            }
                        }
                    }
                }
                else
                {
                    float targetDistance = targetDir.Length();
                    g_targetList.emplace_back(TargetInfo{
                        player.name,
                        screenDistance,
                        headPosOpt.value(),
                        player.pawn,
                        });
                    continue;
                }

            }
        }
    }

    if (g_targetList.empty()) {
        g_lastTargetPawn = 0;
        is_short = false;
        return;
    }

    auto bestTarget = std::min_element(g_targetList.begin(), g_targetList.end(),
        [](const TargetInfo& a, const TargetInfo& b) {
            return a.distance < b.distance;
        });

    g_lastTargetPawn = bestTarget->pawn;

    float smoothSetting = temp_settings.aimbot_smooth;

    bool isSpecialWeapon = false;
    int currentWeaponID = localPlayer.weaponID;
    for (int weaponID : SHORT_RANGE_WEAPONS) {
        if (weaponID == currentWeaponID) {
            isSpecialWeapon = true;
            break;
        }
    }

    if (isSpecialWeapon && !localPlayer.isScoped) {
        if (autoScoped) {
            engine_client->execute_client_cmd("+attack2");
            engine_client->execute_client_cmd("-attack2");
        }
    }
    Vector3 newAngles = CalculateAimAngle(
        local_eye_pos,
        bestTarget->headPos,
        currentViewAngles,
        smoothSetting
    );
    bool shouldCheckTrace = all_settings::aimbot_anitaimbot::aimbot::gqs;
    bool canShoot = true;
    float currentAccuracy, minAccuracy, maxAccuracy, accuracyPercentage;



    if (set_view_angle(newAngles))
    {
        if (shouldCheckTrace)
        {
            CGameTrace pGameTrace = Ray::TraceShape(local_eye_pos, bestTarget->headPos, localPlayer.pawn, 0xC3003);
            canShoot = (pGameTrace.pHitEntity == (void*)bestTarget->pawn);
            if (!canShoot)
            {
                if (autowall)
                {
                    float autowall_fw = temp_settings.autowall_fw;
                    // 定义6个方向的偏移量，使用autowall_fw值
                    const Vector3 offsets[] = {
                        {autowall_fw,0,0},          // 右
                        {-autowall_fw,0,0},          // 左
                        {0,autowall_fw,0},          // 上
                        {0,-autowall_fw,0},          // 下
                        {0,0,autowall_fw}, // 前
                        {0,0,-autowall_fw}  // 后
                    };
                    for (const auto& offset : offsets)
                    {
                        Vector3 eye_pos = local_eye_pos;
                        eye_pos.x += offset.x;
                        eye_pos.y += offset.y;
                        eye_pos.z += offset.z;
                        CGameTrace pGameTrace = Ray::TraceShape(eye_pos, bestTarget->headPos, localPlayer.pawn, 0xC3003);
                        canShoot = (pGameTrace.pHitEntity == (void*)bestTarget->pawn);
                    }
                }
            }
            if (autofire && canShoot && localPlayer.speed <= 80 && bestTarget->distance <= 5)
            {
                if (set_view_angle(newAngles))
                {
                    if (GetWeaponAccuracyInfo(localPlayer, client, currentAccuracy, minAccuracy, maxAccuracy, accuracyPercentage)) {

                        if (accuracyPercentage > 99)
                        {
                            engine_client->execute_client_cmd("+attack");
                            engine_client->execute_client_cmd("-attack");
                        }
                        //MessageWindow::AddColoredMessage("最小精度: %.3f", minAccuracy);
                        //MessageWindow::AddColoredMessage("当前精度: %.3f", currentAccuracy);
                        //MessageWindow::AddColoredMessage("最大精度: %.3f", maxAccuracy);
                        //MessageWindow::AddColoredMessage("精准度: %.1f%%", accuracyPercentage);
                    }

                    return;
                }
            }
        }
        if (autofire && !shouldCheckTrace && canShoot && localPlayer.speed <= 80 && bestTarget->distance <= 5)
        {
            if (set_view_angle(newAngles))
            {
                if (GetWeaponAccuracyInfo(localPlayer, client, currentAccuracy, minAccuracy, maxAccuracy, accuracyPercentage)) {
                    if (accuracyPercentage > 99)
                    {
                        engine_client->execute_client_cmd("+attack");
                        engine_client->execute_client_cmd("-attack");
                    }
                    //MessageWindow::AddColoredMessage("最小精度: %.3f", minAccuracy);
                    //MessageWindow::AddColoredMessage("当前精度: %.3f", currentAccuracy);
                    //MessageWindow::AddColoredMessage("最大精度: %.3f", maxAccuracy);
                    //MessageWindow::AddColoredMessage("精准度: %.1f%%", accuracyPercentage);
                }
                return;
            }   
        }
    }
}

void Weapon_RCS() {
    if (!all_settings::aimbot_anitaimbot::Weapon_RCS::Open_Weapon_RCS)
    {
        return;
    }

    static Vector3 old_aimpunch{ 0.0f, 0.0f, 0.0f };
    static bool back_first = false;
    uintptr_t clientBase = reinterpret_cast<uintptr_t>(GetModuleHandle(L"client.dll"));
    if (!clientBase) return;

    uintptr_t viewAnglesPtr = clientBase + cs2_dumper::offsets::client_dll::dwViewAngles;
    if (!viewAnglesPtr) return;

    Vector3 current_angles = *reinterpret_cast<Vector3*>(viewAnglesPtr);

    auto& playerDataManager = PlayerDataManager::GetInstance();
    auto localPlayer = playerDataManager.GetLocalPlayerData();

    // 检查本地玩家是否有效
    if (!localPlayer.pawn || localPlayer.health <= 0) {
        old_aimpunch = { 0.0f, 0.0f, 0.0f };
        back_first = false;
        return;
    }

    if (WEAPON_NAMES.count(localPlayer.weaponID) == 0) {
        old_aimpunch = { 0.0f, 0.0f, 0.0f };
        back_first = false;
        return;
    }

    auto& weaponSettings = all_settings::aimbot_anitaimbot::Weapon_RCS::Weapon_RCS_settings;

    // 检查武器设置是否存在
    if (weaponSettings.find(localPlayer.weaponID) == weaponSettings.end() ||
        weaponSettings.find(0) == weaponSettings.end()) {
        old_aimpunch = { 0.0f, 0.0f, 0.0f };
        back_first = false;
        return;
    }

    auto& current_settings = weaponSettings[localPlayer.weaponID];
    auto& default_settings = weaponSettings[0];


    all_settings::aimbot_anitaimbot::Weapon_RCS::Weapon_RCSSettings temp_settings;

    if (current_settings.enabled) {
        temp_settings = current_settings;
    }
    else if (default_settings.enabled) {
        temp_settings = default_settings;
    }

    if (!temp_settings.enabled)
    {
        old_aimpunch = { 0.0f, 0.0f, 0.0f };
        back_first = false;
        return;
    }

    float smooth_factor = std::clamp(1.0f - (temp_settings.rcs_smooth / 10.0f), 0.01f, 1.0f);
    auto local_aimpunch = *reinterpret_cast<Vector3*>(localPlayer.pawn + cs2_dumper::schemas::client_dll::C_CSPlayerPawn::m_aimPunchAngle);
    auto shots_fired = *reinterpret_cast<int*>(localPlayer.pawn + cs2_dumper::schemas::client_dll::C_CSPlayerPawn::m_iShotsFired);

    if (shots_fired > 0) {
        if (!back_first) {
            back_first = true;
        }

        Vector3 new_viewAngles;
        new_viewAngles.x = current_angles.x + old_aimpunch.x - (local_aimpunch.x * temp_settings.vertical);
        new_viewAngles.y = current_angles.y + old_aimpunch.y - (local_aimpunch.y * temp_settings.horizontal);

        // Apply smoothness
        new_viewAngles.x = current_angles.x + (new_viewAngles.x - current_angles.x) * smooth_factor;
        new_viewAngles.y = current_angles.y + (new_viewAngles.y - current_angles.y) * smooth_factor;

        set_view_angle(new_viewAngles);

        old_aimpunch.x = local_aimpunch.x * temp_settings.vertical;
        old_aimpunch.y = local_aimpunch.y * temp_settings.horizontal;
    }
    else {
        if (back_first) {
            Vector3 back_firstAngle;
            back_firstAngle.x = current_angles.x + old_aimpunch.x;
            back_firstAngle.y = current_angles.y + old_aimpunch.y;
            back_firstAngle.z = 0.0f;

            // Apply smoothness to reset
            back_firstAngle.x = current_angles.x + (back_firstAngle.x - current_angles.x) * smooth_factor;
            back_firstAngle.y = current_angles.y + (back_firstAngle.y - current_angles.y) * smooth_factor;

            set_view_angle(back_firstAngle);
            back_first = false;
        }
        old_aimpunch = { 0.0f, 0.0f, 0.0f };
    }
}